package com.easyjava.builder;

import com.easyjava.bean.Constants;
import com.easyjava.bean.FieldInfo;
import com.easyjava.bean.TableInfo;
import com.easyjava.init.InitCascade;
import com.easyjava.utils.DateUtils;
import com.easyjava.utils.MyStringUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;

import static com.easyjava.init.InitCascade.TABLE_INFO_MAP;

/**
 * @Author: 小闹心
 * @Description: service类生成器
 * @DateTime: 2024/11/19 13:00
 **/
public class BuildService {
    private static final Logger logger = LoggerFactory.getLogger(BuildService.class);

    public static void execute(TableInfo tableInfo){
        File folder = new File(Constants.PATH_SERVICE);
        if(!folder.exists()){
            folder.mkdirs();
        }
        String className = tableInfo.getBeanName() + "Service";
        File file = new File(folder, className + ".java");
        OutputStream out = null;
        OutputStreamWriter outWriter = null;
        BufferedWriter bw = null;
        try{
            out = new FileOutputStream(file);
            outWriter = new OutputStreamWriter(out, StandardCharsets.UTF_8);
            bw = new BufferedWriter(outWriter);
            bw.write("package " + Constants.PACKAGE_SERVICE + ";");
            bw.newLine();
            bw.newLine();
            bw.write("import " + Constants.PACKAGE_PO + "." + tableInfo.getBeanName() + ";");
            bw.newLine();
            bw.write("import " + Constants.PACKAGE_QUERY + "." + tableInfo.getBeanParamName() + ";");
            bw.newLine();
            bw.write("import " + Constants.PACKAGE_VO + ".PaginationResultVO;");
            bw.newLine();
            bw.newLine();
            // 生成连表查询方法,导入连表查询的查询类
            String tableName = tableInfo.getTableName();
            List<String> tablesList = InitCascade.CASCADE_TABLE_MAP.get(tableName);
            if(tablesList != null){
                // String fields = InitCascade.CASCADE_FIELD_RELATION_MAP.get(tables);
                for(String tables : tablesList){
                    String[] tablesArray = tables.split(",");
                    for(int i = 1; i < tablesArray.length; i++){
                        bw.write("import " + Constants.PACKAGE_QUERY + "." + InitCascade.TABLE_INFO_MAP.get(tablesArray[i]).getBeanName() + Constants.SUFFIX_BEAN_QUERY + ";");
                        bw.newLine();
                    }


                    StringBuilder cascadeClass = new StringBuilder();
                    String[] cascadeTable = tables.split(",");
                    cascadeClass.append(MyStringUtils.upperCaseFirstLetter(cascadeTable[0]));
                    if(cascadeTable.length > 1){
                        cascadeClass.append("And");
                    }
                    for(int i = 1; i < cascadeTable.length;i++){
                        cascadeClass.append(MyStringUtils.upperCaseFirstLetter(TABLE_INFO_MAP.get(cascadeTable[i]).getBeanName()));
                        if(i != cascadeTable.length - 1){
                            cascadeClass.append("And");
                        }
                    }
                    bw.write("import " + Constants.PACKAGE_VO + "." + cascadeClass + ";");
                    bw.newLine();
                }
            }
            bw.write("import java.util.List;");
            bw.newLine();
            bw.newLine();
            // 生成类注释
            BuildComment.createClassComment(bw,tableInfo.getComment() + " Service接口");
            bw.write("public interface " + className + " {");
            bw.newLine();
            bw.newLine();

            BuildComment.createFieldComment(bw,"根据条件查询列表");
            bw.write("\tList<" + tableInfo.getBeanName() + "> findListByParam(" + tableInfo.getBeanParamName() + " param);");
            bw.newLine();
            bw.newLine();

            BuildComment.createFieldComment(bw,"根据条件查询数量");
            bw.write("\tInteger findCountByParam(" + tableInfo.getBeanParamName() + " param);");
            bw.newLine();
            bw.newLine();

            BuildComment.createFieldComment(bw,"分页查询");
            bw.write("\tPaginationResultVO<" + tableInfo.getBeanName() + "> findListByPage(" + tableInfo.getBeanParamName() + " param);");
            bw.newLine();
            bw.newLine();

            BuildComment.createFieldComment(bw,"新增");
            bw.write("\tInteger addOne(" + tableInfo.getBeanName() + " bean);");
            bw.newLine();
            bw.newLine();
            /**
            BuildComment.createFieldComment(bw, "新增或者修改");
            bw.write("\tInteger insertOrUpdate(" + tableInfo.getBeanName() + " bean);");
            bw.newLine();
            bw.newLine();
             */

            /**
            BuildComment.createFieldComment(bw,"批量新增");
            bw.write("\tInteger addBatch(List<" + tableInfo.getBeanName() + "> list);");
            bw.newLine();
            bw.newLine();

            BuildComment.createFieldComment(bw,"批量新增或修改");
            bw.write("\tInteger addOrUpdateBatch(List<" + tableInfo.getBeanName() + "> list);");
            bw.newLine();
            bw.newLine();
             **/


            // 生成唯一索引方法
            Map<String, List<FieldInfo>> keyIndexMap = tableInfo.getKeyIndexMap();
            for(Map.Entry<String, List<FieldInfo>> entry : keyIndexMap.entrySet()){
                List<FieldInfo> keyFields = entry.getValue();
                Integer index = 0;
                StringBuilder methodName = new StringBuilder();
                StringBuilder methodParam = new StringBuilder();
                for(FieldInfo fieldInfo : keyFields){
                    index++;
                    methodName.append(MyStringUtils.upperCaseFirstLetter(fieldInfo.getPropertyName()));
                    methodParam.append(fieldInfo.getJavaType() + " " + MyStringUtils.lowerCaseFirstLetter(fieldInfo.getPropertyName()));
                    if(index < keyFields.size()){
                        methodName.append("And");
                        methodParam.append(", ");
                    }
                }
                BuildComment.createFieldComment(bw,"根据" + methodName + "查询唯一对象");
                bw.write("\t" + tableInfo.getBeanName() + " getBy" + methodName + "(" + methodParam+ ");");
                bw.newLine();
                bw.newLine();

                BuildComment.createFieldComment(bw,"根据" + methodName + "修改对象");
                bw.write("\tInteger updateBy" + methodName + "(" + tableInfo.getBeanName() + " t, " + methodParam +");");
                bw.newLine();
                bw.newLine();

                BuildComment.createFieldComment(bw,"根据" + methodName + "删除对象");
                bw.write("\tInteger deleteBy" + methodName + "(" + methodParam + ");");
                bw.newLine();
                bw.newLine();
            }

            // 创建连表查询方法
            if(tablesList != null){
                for(String tables : tablesList){
                    StringBuilder cascadeClass = new StringBuilder();
                    String[] cascadeTable = tables.split(",");
                    cascadeClass.append(MyStringUtils.upperCaseFirstLetter(cascadeTable[0]));
                    if(cascadeTable.length > 1){
                        cascadeClass.append("And");
                    }
                    for(int i = 1; i < cascadeTable.length;i++){
                        cascadeClass.append(MyStringUtils.upperCaseFirstLetter(TABLE_INFO_MAP.get(cascadeTable[i]).getBeanName()));
                        if(i != cascadeTable.length - 1){
                            cascadeClass.append("And");
                        }
                    }
                    // 创建连表查询方法
                    BuildComment.createFieldComment(bw,cascadeClass + "连表查询");
                    bw.write("\tList<" + cascadeClass + "> " + "select" + cascadeClass + "(");
                    for(int i = 0; i < cascadeTable.length; i++){
                        String bufBeanName = TABLE_INFO_MAP.get(cascadeTable[i]).getBeanName();
                        bw.write(MyStringUtils.upperCaseFirstLetter(bufBeanName) + Constants.SUFFIX_BEAN_QUERY  + " " + MyStringUtils.lowerCaseFirstLetter(bufBeanName));
                        if(i != cascadeTable.length - 1){
                            bw.write(", ");
                        }
                    }
                    bw.write(");");
                    bw.newLine();
                    bw.newLine();
                }
            }

            bw.write("}");
            bw.flush();
        }catch (Exception e){
            logger.error("创建Service对象失败");
        }finally {
            if(bw != null){
                try {
                    bw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(outWriter != null){
                try {
                    outWriter.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(out != null){
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
